//////////////////////////////////////////////////////////////////////////
//
// This file is a part of XORT project.
//
// PROJECT:         
// FILE:            string.h
// AUTHOR:          Vladimir Gumenuk
// DATE:            20-Mar-2008 - included into Xort
// MODIFICATIONS:
//
//
//     Copyright(c) 2014, Vladimir Gumenuk
//     All rights reserved.
//
//     Redistribution and use in source and binary forms, with or without modification, 
//     are permitted provided that the following conditions are met :
//
//     1. Redistributions of source code must retain the above copyright notice, 
//        this list of conditions and the following disclaimer.
//     2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and 
//        the following disclaimer in the documentation and / or other materials provided with the distribution.
//     3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse 
//        or promote products derived from this software without specific prior written permission.
//
//     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
//     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
//     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
//     THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
//     SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
//     OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
//     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
//     OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
//     EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#pragma once

// max hash code value for strings
#define STR_HASH_MAX   111


class string : public xobject
{
public:
    string();
    string( int iInit ); // performs auto conversion digit->string
    string( char cInit );
    string( short sInit );
    string( float fInit );
    string( const char *pstr );
    string( const string& str );
    virtual ~string();

    virtual int Init( symbolref pSymbol, XortNativeInterface *pExternalObj ) { return XORT_OK; }
    virtual void Uninit() { ; }
    virtual dword GetType() { return t_string; };
    virtual int Invoke( dword dwFuncIndex, XRuntime *pRuntime ) { 
        return ERR_METHOD_NOT_IMPL; 
    }
    virtual int Put( dword dwVarIndex, const XortElement& Value ) { 
        return ERR_METHOD_NOT_IMPL;
    }
    virtual int Get( dword dwVarIndex, XortElement& Value ) { 
        return ERR_METHOD_NOT_IMPL; 
    }
    virtual dword GetVariablesCount() { return 0; }
    virtual symbolref get_Symbol() { return 0; }
    virtual symbolref get_Method( dword dwIdx ) { return 0; }

    string& operator= ( const string& Var );
    string& operator= ( char cVal );
    string& operator+= ( char cVal );
    string& operator= ( short sVal );
    string& operator= ( int iVal );
    string& operator= ( float fVal );
    string& operator= ( const char *pszVal );
    string& operator+= ( const char *pszVal );
    string& operator+ ( const string& Var );
    string& operator+= ( const string& Var );

    bool operator== ( const string& Var );
    bool operator== ( const char *pszVal );
    bool operator!= ( const string& Var );
    bool operator!= ( const char *pszVar );
    bool operator<  ( const string& Var );
    bool operator>  ( const string& Var );
    bool operator>= ( const string& Var );

    inline operator const char*() const {
        return m_pchData;
    }
    
//    inline operator lpcstr() const {
//        return m_pchData;
//    }

    inline char operator[] ( dword iPos )  {
            return m_pchData[iPos];
    }

    inline bool IsEmpty() const {
        return ( m_pchData == 0 );
    }

    STATIC int    __cdecl strcmp( const char* src, const char* dst );
    STATIC char * __cdecl strrchr( const char *str, int ch );
    STATIC char * __cdecl strcpy( char * dst, const char * src );
    STATIC dword  __cdecl strlen( const char * str  );
    STATIC char * __cdecl strstr( const char * str1, const char * str2 );
    STATIC char * __cdecl strcat( char * dst, const char * src );

    void         Attach( char* lpszStr );
    dword        Add( const char* lpszStr );
    dword        Assign( const char* lpszStr );
    char *       Detach();
    inline void  Empty() { clear(); m_pchData = 0; }
    void         Format( const char *pszFmt, ... );
    void         FormatOneText( const char *pszFmt, const char *pszText );
    bool         AllocBuffer( dword size );
    char *       GetBuffer();
    char         CharAt( dword dwPos );
    int          Compare( const char *pstr );
    dword        Length();
    void         TrimRight( char c );
    // inserts text at the specified position
    bool         Insert( const char *lpstrText, dword iAt );
    // return number of places that were replacement was done
    dword Replace( const char *lpstrOld, const char *lpstrNew, dword dwNumReplacements = 0 );
    // remove part of string, returns the position where it was removed
    dword Cut( const char *lpstrWhat );

    // Find the last occurrence of character 'ch'
    int ReverseFind( char ch );

    void Truncate( dword dwStartPos ); // removes all characters after specified position

    // returns substring from starting position
    string Substring( int iStartPos );

    void CopyToBuffer( char *pszBuf ) const;

    dword        Append( char ch );
    dword        hasChr( byte ch ) const; // returns the 1-based index of the character if found, 0 otherwise
    double       doubleValue(); // converts string to digit
    float        floatValue();
    int          intValue();
    qlong        longValue();

    void double2Str( double d );
    void float2Str( float f );
    void dword2Str( dword d );
    void word2Str( word w );
    void byte2Str( byte b );

    // returns the hash value of the string in range 0 - STR_HASH_MAX-1
    unsigned long get_hashCode() const;

protected:
    void clear();
    void attach( const string& Var );
    dword copy_string( const char *pszSrc );
    dword plus_string( const char *pszSrc );
    void assign_char( char ch );
    
    char    *m_pchData;
    dword    m_dwLength;
};
    
string __cdecl operator+ ( const char *s1, const string& s2 );
string __cdecl operator+ ( const string& s1, const char *s2 );
string __cdecl operator+ ( const string& s1, const string& s2 );
string __cdecl operator+ ( const string& s1, int iVal );
string __cdecl operator+ ( const string& s1, float fVal );

typedef string* stringref;